#include "../../config.h"

#include <glibmm/i18n.h>

#include "../application.h"
#include "../conf.h"
#include "p_command.h"
#include "p_macros.h"

namespace gpyp {
namespace pref {

//========================
// PlayerList
void PlayerList::icon_on_cell_data(Gtk::CellRenderer   *cell,
                                   const Gtk::TreeIter &iter) {
  dynamic_cast<CellRendererIcon *>(cell)
    ->set_icon_name(*get_item(iter)->icon());
}
void PlayerList::name_on_cell_data(Gtk::CellRenderer   *cell,
                                   const Gtk::TreeIter &iter) {
  dynamic_cast<Gtk::CellRendererText *>(cell)
    ->property_text() = *get_item(iter)->name();
}
void PlayerList::command_on_cell_data(Gtk::CellRenderer   *cell,
                                      const Gtk::TreeIter &iter) {
  dynamic_cast<Gtk::CellRendererText *>(cell)
    ->property_text() = *get_item(iter)->command();
}
void PlayerList::type_on_cell_data(Gtk::CellRenderer   *cell,
                                   const Gtk::TreeIter &iter) {
  dynamic_cast<Gtk::CellRendererText *>(cell)
    ->property_text() = *get_item(iter)->type();
}
void PlayerList::auto_play_on_cell_data(Gtk::CellRenderer   *cell,
                                        const Gtk::TreeIter &iter) {
  dynamic_cast<Gtk::CellRendererToggle *>(cell)
    ->set_active(*get_item(iter)->auto_play());
}

void PlayerList::icon_on_edited(const Glib::ustring &path,
                                const Glib::ustring &new_icon_name) {
  get_item(path)->icon() = new_icon_name;
}
void PlayerList::name_on_edited(const Glib::ustring &path,
                                const Glib::ustring &new_text) {
  get_item(path)->name() = new_text;
}
void PlayerList::command_on_edited(const Glib::ustring &path,
                                   const Glib::ustring &new_text) {
  get_item(path)->command() = new_text;
}
void PlayerList::type_on_edited(const Glib::ustring &path,
                                const Glib::ustring &new_text) {
  get_item(path)->type() = new_text;
}
void PlayerList::auto_play_on_toggled(const Glib::ustring &path) {
  ConfMain::RefPlayer player = get_item(path);
  player->auto_play() = !*player->auto_play();
}

PlayerList::PlayerList(Application &app, Gtk::Window &parent) :
  ListView<ConfMain::PlayerCollection>(app.conf().command()->players()),
  app_             (app),
  renderer_icon_   (parent),
  column_icon_     (_("Icon"),    renderer_icon_),
  column_name_     (_("Name"),    renderer_name_),
  column_command_  (_("Command"), renderer_command_),
  column_type_     (_("Type"),    renderer_type_),
  column_auto_play_("A",          renderer_auto_play_)
{
  renderer_name_.property_editable() = true;
  renderer_command_.property_editable() = true;
  renderer_command_.property_ellipsize() = Pango::ELLIPSIZE_END;
  renderer_type_.property_editable() = true;
  renderer_type_.property_ellipsize() = Pango::ELLIPSIZE_END;
  renderer_auto_play_.property_activatable() = true;

#define CELL_DATA(N)                                                    \
  column_##N##_.set_cell_data_func(renderer_##N##_, sigc::mem_fun(*this, &PlayerList::N##_on_cell_data));
  CELL_DATA(icon);
  CELL_DATA(name);
  CELL_DATA(command);
  CELL_DATA(type);
  CELL_DATA(auto_play);
#undef CELL_DATA

#define CONN_EDITED(N, S)                                       \
  renderer_##N##_.signal_##S()                                  \
    .connect(sigc::mem_fun(*this, &PlayerList::N##_on_##S));
  CONN_EDITED(icon,      edited);
  CONN_EDITED(name,      edited);
  CONN_EDITED(command,   edited);
  CONN_EDITED(type,      edited);
  CONN_EDITED(auto_play, toggled);
#undef CONN_EDITED

  column_command_.set_expand(true);

  append_column(column_icon_);
  append_column(column_name_);
  append_column(column_command_);
  append_column(column_type_);
  append_column(column_auto_play_);

#ifdef GTK_HAVE_TOOLTIP
  set_tooltip_text(_("\"A\": Only for auto play"));
#endif
}

//========================
// PlayerBox::PresetMenu::Item
void PlayerBox::PresetMenu::Item::on_activate() {
  app_.conf().command()->players()
    ->add_item(preset_.name, preset_.command, preset_.icon);
}

PlayerBox::PresetMenu::Item::Item(Application &app, const Preset &preset) :
  Gtk::ImageMenuItem(preset.name),
  app_              (app),
  preset_           (preset)
{
  image_.set(IconManager::load_icon(preset_.icon, GTK_ICON_SIZE_MENU));
  set_image(image_);
}

//========================
// PlayerBox::PresetMenu
PlayerBox::PresetMenu::PresetMenu(Application &app) {
  const Preset *p = ConfMain::PlayerCollection::PRESETS;
  for(; p->name; ++p) {
    Item *mi = new Item(app, *p);
    append(*Gtk::manage(mi));
  }
  show_all();
}

//========================
// PlayerBox
void PlayerBox::preset_on_clicked() {
  preset_menu_.popup(1, GDK_CURRENT_TIME);
}

PlayerBox::PlayerBox(Application &app, Gtk::Window &parent) :
  Gtk::VBox   (false, 2),
  playerlist_ (app, parent),
  preset_menu_(app)
{
  Gtk::ScrolledWindow *sw1 = Gtk::manage(new Gtk::ScrolledWindow());
  sw1->add(playerlist_);
  sw1->set_shadow_type(Gtk::SHADOW_IN);
  sw1->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
  pack_start(*sw1);

  Gtk::Button *b_u = Gtk::manage(new Gtk::Button(Gtk::Stock::GO_UP));
  Gtk::Button *b_d = Gtk::manage(new Gtk::Button(Gtk::Stock::GO_DOWN));
  Gtk::Button *b_a = Gtk::manage(new Gtk::Button(Gtk::Stock::ADD));
  Gtk::Button *b_r = Gtk::manage(new Gtk::Button(Gtk::Stock::REMOVE));
  Gtk::Button *b_p = Gtk::manage(new Gtk::Button(_("_Preset"), true));
  b_u->signal_clicked().connect(sigc::mem_fun(playerlist_, &PlayerList::up));
  b_d->signal_clicked().connect(sigc::mem_fun(playerlist_, &PlayerList::down));
  b_a->signal_clicked().connect(sigc::mem_fun(playerlist_, &PlayerList::add));
  b_r->signal_clicked().connect(sigc::mem_fun(playerlist_, &PlayerList::remove));
  b_p->signal_clicked().connect(sigc::mem_fun(*this, &PlayerBox::preset_on_clicked));
  Gtk::HButtonBox *h1 =
    Gtk::manage(new Gtk::HButtonBox(Gtk::BUTTONBOX_END, 2));
  h1->pack_start(*b_u, false, false);
  h1->pack_start(*b_d, false, false);
  h1->pack_start(*b_a, false, false);
  h1->pack_start(*b_r, false, false);
  h1->pack_start(*b_p, false, false);
  pack_start(*h1, false, false);
}

//========================
// Command
Command::Command(Application &app, Gtk::Window &parent) :
  Gtk::VBox   (false, 2),
  peercast_   (ConfMain::BuiltInCommand::PRESET_PEERCAST),
  pcraw_proxy_(ConfMain::BuiltInCommand::PRESET_PCRAW_PROXY),
  terminal_   (ConfMain::BuiltInCommand::PRESET_TERMINAL),
  webbrowser_ (ConfMain::BuiltInCommand::PRESET_WEBBROWSER),
  bbsbrowser_ (ConfMain::BuiltInCommand::PRESET_BBSBROWSER),
  player_     (app, parent)
{
  Gtk::Table *t1 = Gtk::manage(new Gtk::Table());
  TABLE_LABEL(*t1, 0, _("PeerCast"));
  TABLE_LABEL(*t1, 1, _("pcraw_proxy"));
  TABLE_LABEL(*t1, 2, _("Terminal"));
  TABLE_LABEL(*t1, 3, _("Web browser"));
  TABLE_LABEL(*t1, 4, _("2ch browser"));
#define TABLE_VALUE(T, R, W)                                    \
  (T).attach(W, 1, 2, R, (R) + 1,                               \
             Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK | Gtk::FILL)
  TABLE_VALUE(*t1, 0, peercast_);
  TABLE_VALUE(*t1, 1, pcraw_proxy_);
  TABLE_VALUE(*t1, 2, terminal_);
  TABLE_VALUE(*t1, 3, webbrowser_);
  TABLE_VALUE(*t1, 4, bbsbrowser_);
  TABLE_SPACING(*t1, 2, 2);
  pack_start(*t1, false, false);

  player_.set_border_width(2);

  Gtk::Frame *f1 = Gtk::manage(new Gtk::Frame(_("Player")));
  f1->add(player_);
  pack_start(*f1);

  ConfMain::RefBuiltInCommand c = app.conf().command();
#define ATTACH_COMMAND(N)                                       \
  c->N()->command()->attach(N##_.get_entry()->property_text())
  ATTACH_COMMAND(peercast);
  ATTACH_COMMAND(pcraw_proxy);
  ATTACH_COMMAND(terminal);
  ATTACH_COMMAND(webbrowser);
  ATTACH_COMMAND(bbsbrowser);
#undef ATTACH_COMMAND
}

}/*pref*/
}/*gpyp*/
